import os
import logging
from docx import Document
import re
from docx.oxml import parse_xml
from docx.shared import Pt
from server.config.log import logger
from server.report.config.config import Config
from datetime import datetime
import zipfile


class WordDocumentProcessor:
    """Word文档处理类，负责将内容转换并插入到Word文档中"""
    
    def __init__(self):
        self.config = Config()
        self.scene_dir = self.config.scene_dir
        self.output_dir = self.config.output_dir
    
    def process_document(self, content_dict: dict, scene_name: str):
        """处理整个文档：替换占位符并保存"""
        logger.info("开始处理Word文档")

        template_path = os.path.join(self.config.scene_dir, scene_name, "word_template.docx") 
        doc = Document(template_path)

        timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
        output_path = os.path.join(self.config.output_dir, f"credit_report_internal_{timestamp}.docx")
        
        # 替换占位符
        self._replace_placeholders(doc, content_dict)
        
        # 设置文档格式
        self._format_document(doc)
        
        # 保存文档
        self._save_document(doc, output_path)
        
        logger.info("Word文档处理完成")

        return output_path
    
    def _replace_placeholders(self, doc: Document, content_dict: dict):
        """替换Word文档中的占位符"""
        logger.info(f"开始替换占位符，共 {len(content_dict)} 个")
        
        replaced_count = 0
        
        # 为了避免在迭代过程中修改文档结构导致的问题，
        # 我们采用while循环，每次都重新查找占位符
        remaining_placeholders = list(content_dict.items())
        
        while remaining_placeholders:
            placeholder, content = remaining_placeholders.pop(0)
            logger.debug(f"处理占位符: {placeholder}")
            
            placeholder_found = False
            
            # 检查段落中的占位符
            for current_index, paragraph in enumerate(doc.paragraphs):
                if placeholder in paragraph.text:
                    logger.debug(f"在段落 {current_index} 中找到占位符: {placeholder}")
                    
                    # 检查内容是否包含Markdown格式
                    if self._is_markdown_content(content):
                        logger.debug(f"检测到Markdown格式内容，序号{current_index}，进行格式转换: {placeholder}")
                        logger.debug(f"分析结果 markdown: {content}")
                        self._convert_markdown_to_word_element(doc, content, paragraph, current_index)
                    else:
                        # 普通文本替换
                        paragraph.text = paragraph.text.replace(placeholder, content)
                    
                    replaced_count += 1
                    placeholder_found = True
                    logger.debug(f"替换占位符: {placeholder}")
                    
                    # 找到并处理了占位符后，跳出当前循环
                    break
            
            # 如果在段落中没有找到，检查表格中的占位符
            if not placeholder_found:
                for table_index, table in enumerate(doc.tables):
                    table_placeholder_found = False
                    for row_index, row in enumerate(table.rows):
                        for cell_index, cell in enumerate(row.cells):
                            # 检查单元格中的每个段落
                            for para_index, cell_paragraph in enumerate(cell.paragraphs):
                                if placeholder in cell_paragraph.text:
                                    logger.debug(f"在表格 {table_index} 行 {row_index} 列 {cell_index} 段落 {para_index} 中找到占位符: {placeholder}")
                                    
                                    # 检查内容是否包含Markdown格式
                                    if self._is_markdown_content(content):
                                        logger.debug(f"检测到Markdown格式内容，在表格中进行格式转换: {placeholder}")
                                        # 对于表格中的内容，我们需要特殊处理
                                        self._convert_markdown_to_table_cell(cell, content, cell_paragraph)
                                    else:
                                        # 普通文本替换
                                        cell_paragraph.text = cell_paragraph.text.replace(placeholder, content)
                                    
                                    replaced_count += 1
                                    placeholder_found = True
                                    table_placeholder_found = True
                                    logger.debug(f"在表格中替换占位符: {placeholder}")
                                    break
                            
                            if table_placeholder_found:
                                break
                        
                        if table_placeholder_found:
                            break
                    
                    if table_placeholder_found:
                        break
            
            if not placeholder_found:
                logger.warning(f"未找到占位符: {placeholder}")
        
        logger.info(f"占位符替换完成，共替换 {replaced_count} 处")
    
    def _process_line_with_formatting(self, paragraph, line):
        """处理单行内容，支持粗体格式"""
        line = line.replace("# ","").replace("##","").replace("###","")
        if not line or line == "---":
            # 空行
            paragraph.text = ""
            return
        
        # 清空段落内容
        paragraph.clear()
        
        # 首先处理编号加粗：匹配以数字开头的编号部分
        # 包括：1. 1： 1。 或者单独的数字后直接是空格或换行
        # 首先检查是否为需要整行加粗的情况：以数字开头且没有逗号、句号、分号
        whole_line_bold_pattern = r'^\s*\d+\s*[\.:：。].*$'
        punctuation_pattern = r'[，。；,;.]'
        
        # 检查是否匹配整行加粗条件
        if (re.match(whole_line_bold_pattern, line) and 
            not re.search(punctuation_pattern, line)):
            # 整行加粗
            run = paragraph.add_run(line)
            run.bold = True
            return
        
        # 否则按原逻辑处理编号部分加粗
        number_pattern = r'^(\d+\s*[\.:：。])'
        number_match = re.match(number_pattern, line)
        
        if number_match:
            # 有编号的情况
            number_part = number_match.group(1)  # 编号部分
            remaining_text = line[len(number_part):]  # 剩余文本
            
            # 添加加粗的编号部分
            number_run = paragraph.add_run(number_part)
            number_run.bold = True
            
            # 处理剩余文本中的**粗体标记
            if remaining_text:
                bold_pattern = r'\*\*(.*?)\*\*'
                parts = re.split(bold_pattern, remaining_text)
                
                # 处理分割后的部分
                for i, part in enumerate(parts):
                    if not part:  # 跳过空字符串
                        continue
                        
                    if i % 2 == 0:
                        # 偶数索引是普通文本
                        if part:
                            run = paragraph.add_run(part)
                            # 设置字体为宋体5号
                            run.font.name = '宋体'
                            run.font.size = Pt(10.5)
                    else:
                        # 奇数索引是粗体文本（被**包围的内容）
                        if part:
                            run = paragraph.add_run(part)
                            run.bold = True
                            # 设置字体为宋体5号
                            run.font.name = '宋体'
                            run.font.size = Pt(10.5)
        else:
            # 没有编号的情况，只处理**粗体标记
            bold_pattern = r'\*\*(.*?)\*\*'
            parts = re.split(bold_pattern, line)
            
            # 处理分割后的部分
            for i, part in enumerate(parts):
                if not part:  # 跳过空字符串
                    continue
                    
                if i % 2 == 0:
                    # 偶数索引是普通文本
                    if part:
                        run = paragraph.add_run(part)
                        # 设置字体为宋体5号
                        run.font.name = '宋体'
                        run.font.size = Pt(10.5)
                else:
                    # 奇数索引是粗体文本（被**包围的内容）
                    if part:
                        run = paragraph.add_run(part)
                        run.bold = True
                        # 设置字体为宋体5号
                        run.font.name = '宋体'
                        run.font.size = Pt(10.5)
    
    def _convert_markdown_to_word_element(self, doc, markdown_content, target_paragraph, target_index=None):
        """将Markdown内容转换为Word文档元素"""
        try:
            # 清空目标段落的现有内容
            target_paragraph.clear()
            
            # 按换行符分割markdown内容
            lines = markdown_content.split('\n')
            
            # 获取段落的父元素，用于插入新段落
            parent = target_paragraph._element.getparent()
            target_index = list(parent).index(target_paragraph._element)
            
            # 检测并处理Markdown表格
            i = 0
            insert_index = 0
            while i < len(lines):
                # 检查当前行是否为表格开始
                if self._is_markdown_table_start(lines, i):
                    # 提取表格数据
                    table_data, table_end_index = self._extract_markdown_table(lines, i)
                    
                    # 如果是第一个元素，在target_paragraph位置插入表格
                    if i == 0:
                        # 在target_paragraph之前插入表格
                        table = self._create_word_table(doc, table_data)
                        parent.insert(target_index, table._element)
                        # 清空target_paragraph但保留它
                        target_paragraph.text = ""
                    else:
                        # 在当前位置插入表格
                        table = self._create_word_table(doc, table_data)
                        parent.insert(target_index + insert_index, table._element)
                    
                    # 跳过已处理的表格行
                    i = table_end_index + 1
                    insert_index += 1
                    continue
                
                # 处理普通文本行
                if i == 0:
                    current_paragraph = target_paragraph
                else:
                    # 创建新段落
                    new_para = doc.add_paragraph()
                    # 将新段落插入到正确位置
                    parent.insert(target_index + insert_index, new_para._element)
                    current_paragraph = new_para
                
                # 处理当前行的内容
                self._process_line_with_formatting(current_paragraph, lines[i])
                i += 1
                insert_index += 1
            
            # 如果没有内容，至少保留一个空段落
            if not lines or (len(lines) == 1 and not lines[0].strip()):
                target_paragraph.text = ""
                
        except Exception as e:
            logger.exception(f"转换Markdown内容时出错: {e}")
            # 出错时回退到原始方法
            target_paragraph.text = markdown_content
    
    def _is_markdown_table_start(self, lines, start_index):
        """检查指定位置是否为Markdown表格的开始"""
        if start_index >= len(lines):
            return False
        
        # 检查当前行是否包含表格分隔符 |
        current_line = lines[start_index].strip()
        if not current_line or '|' not in current_line:
            return False
        
        # 检查下一行是否为表格分隔行（包含 |---| 模式）
        if start_index + 1 >= len(lines):
            return False
        
        next_line = lines[start_index + 1].strip()
        # 表格分隔行应该包含 | 和 - 字符
        if '|' in next_line and '-' in next_line:
            return True
        
        return False
    
    def _extract_markdown_table(self, lines, start_index):
        """从指定位置提取Markdown表格数据"""
        table_data = []
        current_index = start_index
        
        # 提取表头
        header_line = lines[current_index].strip()
        if header_line.startswith('|') and header_line.endswith('|'):
            header_line = header_line[1:-1]  # 移除首尾的 |
        header_cells = [cell.strip() for cell in header_line.split('|')]
        table_data.append(header_cells)
        current_index += 1
        
        # 跳过分隔行
        if current_index < len(lines):
            current_index += 1
        
        # 提取数据行
        while current_index < len(lines):
            line = lines[current_index].strip()
            if not line or '|' not in line:
                break
            
            # 处理数据行
            if line.startswith('|') and line.endswith('|'):
                line = line[1:-1]  # 移除首尾的 |
            data_cells = [cell.strip() for cell in line.split('|')]
            table_data.append(data_cells)
            current_index += 1
        
        return table_data, current_index - 1
    
    def _create_word_table(self, doc, table_data):
        """根据表格数据创建Word表格"""
        if not table_data or len(table_data) < 1:
            return None
        
        # 创建表格
        rows = len(table_data)
        cols = len(table_data[0]) if table_data else 0
        table = doc.add_table(rows=rows, cols=cols)
        
        # 设置表格样式，使用更通用的样式或添加错误处理
        try:
            table.style = 'Table Grid'
        except KeyError:
            try:
                # 尝试使用其他常见的表格样式
                table.style = 'Light Grid Accent 1'
            except KeyError:
                try:
                    table.style = 'Medium Grid 1 Accent 1'
                except KeyError:
                    # 如果都不存在，使用默认样式并手动设置边框
                    logger.warning("未找到预设表格样式，使用默认样式")
                    
                    # 为表格添加边框
                    tbl = table._tbl
                    tblPr = tbl.tblPr
                    
                    # 添加表格边框设置
                    tblBorders = parse_xml(r'<w:tblBorders {}><w:top w:val="single" w:sz="4" w:space="0" w:color="000000"/><w:left w:val="single" w:sz="4" w:space="0" w:color="000000"/><w:bottom w:val="single" w:sz="4" w:space="0" w:color="000000"/><w:right w:val="single" w:sz="4" w:space="0" w:color="000000"/><w:insideH w:val="single" w:sz="4" w:space="0" w:color="000000"/><w:insideV w:val="single" w:sz="4" w:space="0" w:color="000000"/></w:tblBorders>'.format('xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"'))
                    tblPr.append(tblBorders)
        
        # 填充表格数据
        for row_idx, row_data in enumerate(table_data):
            for col_idx, cell_data in enumerate(row_data):
                if col_idx < len(table.rows[row_idx].cells):
                    cell = table.rows[row_idx].cells[col_idx]
                    cell.text = str(cell_data.replace("**",""))

                    # 设置字体为宋体5号
                    for paragraph in cell.paragraphs:
                        for run in paragraph.runs:
                            run.font.name = '宋体'
                            run.font.size = Pt(10.5)
                    
                    # 如果是表头行，设置为粗体
                    if row_idx == 0:
                        for paragraph in cell.paragraphs:
                            for run in paragraph.runs:
                                run.bold = True
        
        return table
    
    def _is_markdown_content(self, content: str) -> bool:
        """检测内容是否包含Markdown格式"""
        markdown_indicators = [
            '# ', '## ', '### ',  # 标题
            '- ', '* ', '+ ',     # 无序列表
            '1. ', '2. ',         # 有序列表
            '**', '__',           # 粗体
            '*', '_',             # 斜体
            '|',                  # 表格
            '```',                # 代码块
        ]
        
        return any(indicator in content for indicator in markdown_indicators)
    
    def _format_document(self, doc: Document):
        """设置文档格式"""
        logger.info("设置文档行距为1.5倍")
        
        # 设置段落行距
        for paragraph in doc.paragraphs:
            paragraph.paragraph_format.line_spacing = 1.5
        
        # 设置表格中的行距
        for table in doc.tables:
            for row in table.rows:
                for cell in row.cells:
                    for paragraph in cell.paragraphs:
                        paragraph.paragraph_format.line_spacing = 1.5
    
        # 处理连续换行符：将连续两个换行符替换为一个换行符
        logger.info("处理文档中的连续换行符")
        self._remove_consecutive_line_breaks(doc)
    
    def _remove_consecutive_line_breaks(self, doc: Document):
        """移除文档中的连续换行符"""
        try:
            # 处理普通段落
            paragraphs_to_remove = []
            
            for i, paragraph in enumerate(doc.paragraphs):
                # 检查当前段落是否为空
                if not paragraph.text.strip():
                    # 检查下一个段落是否也为空
                    if i + 1 < len(doc.paragraphs) and not doc.paragraphs[i + 1].text.strip():
                        # 标记当前空段落为待删除
                        paragraphs_to_remove.append(paragraph)
            
            # 删除连续的空段落（保留一个）
            for paragraph in paragraphs_to_remove:
                # 获取段落的父元素
                parent = paragraph._element.getparent()
                if parent is not None:
                    parent.remove(paragraph._element)
            
            # 处理表格中的段落
            for table in doc.tables:
                for row in table.rows:
                    for cell in row.cells:
                        cell_paragraphs_to_remove = []
                        
                        for i, paragraph in enumerate(cell.paragraphs):
                            # 检查当前段落是否为空
                            if not paragraph.text.strip():
                                # 检查下一个段落是否也为空
                                if i + 1 < len(cell.paragraphs) and not cell.paragraphs[i + 1].text.strip():
                                    # 标记当前空段落为待删除
                                    cell_paragraphs_to_remove.append(paragraph)
                            
                            # 删除表格单元格中连续的空段落
                            for paragraph in cell_paragraphs_to_remove:
                                parent = paragraph._element.getparent()
                                if parent is not None:
                                    parent.remove(paragraph._element)
            
            logger.info(f"已移除 {len(paragraphs_to_remove)} 个连续的空段落")
            
        except Exception as e:
            logger.error(f"处理连续换行符时出错: {e}")

    def _save_document(self, doc: Document, output_path: str):
        """保存文档"""
        logger.info(f"开始保存文档到: {output_path}")
        
        # 确保输出目录存在
        output_dir = os.path.dirname(output_path)
        if not os.path.exists(output_dir):
            os.makedirs(output_dir)
            logger.info(f"创建输出目录: {output_dir}")
        
        doc.save(output_path)
        logger.info(f"文档保存成功: {output_path}")

    def _convert_markdown_to_table_cell(self, cell, markdown_content, target_paragraph):
        """将Markdown内容转换为表格单元格中的Word元素"""
        try:
            # 清空目标段落的现有内容
            target_paragraph.clear()
            
            # 按换行符分割markdown内容
            lines = markdown_content.split('\n')
            
            # 对于表格单元格，我们简化处理，主要处理文本格式
            for i, line in enumerate(lines):
                if i == 0:
                    # 第一行使用现有段落
                    current_paragraph = target_paragraph
                else:
                    # 后续行创建新段落
                    current_paragraph = cell.add_paragraph()
                
                # 处理当前行的内容（简化版，主要处理粗体）
                self._process_line_with_formatting(current_paragraph, line)
                
        except Exception as e:
            logger.exception(f"转换表格单元格Markdown内容时出错: {e}")
            # 出错时回退到原始方法
            target_paragraph.text = markdown_content


